# -*- coding: utf-8 -*-
"""
"""

from sqlalchemy import *
from sqlalchemy.orm import mapper, relation
from sqlalchemy import Table, ForeignKey, Column
from sqlalchemy.types import Integer, Unicode

from abserver.model import DeclarativeBase, metadata, DBSession



class Product(DeclarativeBase):
    # table options
    __tablename__ = 'product'

    # columns
    product_id = Column(Integer, primary_key=True, autoincrement=True)
    product_name = Column(Unicode(64), nullable=False)
    product_owner = Column(Unicode(32), nullable=True)
    product_poc = Column(Unicode(64), nullable=True)
    product_description = Column(Unicode(), nullable=True) # wiki markup

    component_id = Column(Integer, ForeignKey('component.component_id'))

    # relationships
    component = relation('Component', backref='product')
    ## builderschedules

    def __init__(self, product_name, component, product_owner=None,
                 product_poc=None, product_description=None):
        self.product_name = product_name
        self.component = component
        self.product_owner = product_owner
        self.product_poc = product_poc
        self.product_description = product_description

    @classmethod
    def get_product(cls, name, component=None):
        product = DBSession.query(cls).filter(cls.product_name==name).first()
        if not product:
            product = cls(name, component)
            DBSession.add(product)
        return product
    
    @classmethod
    def get(cls, product_id):
        product = DBSession.query(cls).filter(cls.product_id==product_id).first()
        return product

    def get_views(self):
        component_p = self.component
        q = BuildView.query()
        # buildviews acceptable with respect to the branch of the component
        q11 = BuildView.query().join(BuildView.buildview_branch).join(Branch.components).filter(Component.component_id==component_p.component_id).all()
        q12 = BuildView.query().filter(BuildView.buildview_branch==None).all()
        Q = BuildView.query().filter(or_(BuildView.buildview_id.in_([v.buildview_id for v in q11]),
                                          BuildView.buildview_id.in_([v.buildview_id for v in q12])))
        # buildviews acceptable with respect to the component itself
        q21 = BuildView.query().join(BuildView.buildview_component).filter(Component.component_id==component_p.component_id).all()
        q22 = BuildView.query().filter(BuildView.buildview_component==None).all()
        Q = Q.filter(or_(BuildView.buildview_id.in_([v.buildview_id for v in q21]),
                                          BuildView.buildview_id.in_([v.buildview_id for v in q22])))
        # buildviews acceptable with respect to the blessing level
        q31 = BuildView.query().join(BuildView.bless_levels).join(BuildBlessing.blessed_tasks).join(Task.build)
        q31 = q31.filter(and_(
                              or_(BuildView.buildview_start_time==None, Build.sccs_time > BuildView.buildview_start_time),
                              or_(BuildView.buildview_end_time==None, Build.sccs_time < BuildView.buildview_end_time)
                              ))
        q31 = q31.filter(Build.build_id.in_([bl.build_id for bl in component_p.builds]))
        q31 = q31.join(Build.branch).filter(Branch.branch_id.in_([br.branch_id for br in component_p.branches])).all()
        q32 = BuildView.query().filter(BuildView.bless_levels==None).all()
        Q = Q.filter(or_(BuildView.buildview_id.in_([v.buildview_id for v in q31]),
                         BuildView.buildview_id.in_([v.buildview_id for v in q32])))
        
        # synthesis
        return Q.all()

    @classmethod
    def get_product_listing(cls):
        products = cls.query.all()
        return [ (p.product_id, p.product_name) for p in products ]
